using Circus.CodeEditor;
using Circus.CodeEditor.TextSource;
using Circus.Syntax;
using Circus.Syntax.CodeCompletion;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Circus.CodeEditor.CodeCompletion
{
	public class HintSyntaxPaint : HtmlSyntaxPaint
	{
		internal class HintItem : StringItem
		{
			private int width;
			public int Width
			{
				get
				{
					return this.width;
				}
			}
			public HintItem(string s, int width) : base(s)
			{
				this.width = width;
			}
		}
		private const int drawTop = 1;
		private const int drawBottom = 4;
		private const int drawLeft = 2;
		private const int arrowWidth = 10;
		private const int arrowHeight = 8;
		private const int arrowTop = 2;
		private const int arrowBottom = 8;
		private IList<StringItem> strings;
		private int selectedIndex;
		private string nameStr = string.Empty;
		private Point startPos;
		public bool NeedArrows
		{
			get
			{
				return base.Provider != null && base.Provider.Count > 1;
			}
		}
		public Rectangle LeftArrowArea
		{
			get
			{
				return new Rectangle(2, 2, 10, 8);
			}
		}
		public Point StartPos
		{
			get
			{
				return this.startPos;
			}
			set
			{
				this.startPos = value;
			}
		}
		[Description("Represents an array of strings displayed in a hint.")]
		public IList<StringItem> Strings
		{
			get
			{
				return this.strings;
			}
		}
		private int MeasureArrows()
		{
			int result;
			if (this.NeedArrows)
			{
				string text = string.Format(StringConsts.NofMstr, this.selectedIndex + 1, base.Provider.Count);
				result = this.painter.measureString(text) + 20 + 8;
			}
			else
			{
				result = 0;
			}
			return result;
		}
		private void DrawArrows()
		{
			string text = string.Format(StringConsts.NofMstr, this.selectedIndex + 1, base.Provider.Count);
			int num = this.painter.measureString(text);
			this.painter.BackColor = Consts.DefaultPopupBackColor;
			this.painter.FillRectangle(2, 2, 10, 8);
			int num2 = 6 + num + 10;
			this.painter.FillRectangle(num2, 2, 10, 8);
			Point point = new Point(3, 10);
			Point point2 = new Point(7, 4);
			Point point3 = new Point(10, 10);
			Point[] points = new Point[]
			{
				point,
				point2,
				point3
			};
			this.painter.DrawPolygon(points, EditConsts.DefaultArrowForeColor);
			point = new Point(num2 + 1, 5);
			point2 = new Point(num2 + 5, 11);
			point3 = new Point(num2 + 10 - 2, 5);
			Point[] points2 = new Point[]
			{
				point,
				point2,
				point3
			};
			this.painter.DrawPolygon(points2, EditConsts.DefaultArrowForeColor);
			this.painter.TextOut(text, text.Length, 14, 1);
		}
		protected override void AddLine(string s, StringItemInfo[] data)
		{
			bool flag = this.strings.Count == 0;
			if (s == string.Empty)
			{
				this.strings.Add(new HintSyntaxPaint.HintItem(string.Empty, 0));
			}
			else
			{
				int i = 0;
				int length = s.Length;
				int num = EditConsts.MaxHintWindowWidth;
				if (flag)
				{
					num -= this.MeasureArrows();
				}
				while (i < length)
				{
					int num2;
					int width = this.MeasureLine(s, data, i, length, num, out num2, true, false, true);
					if (i + num2 < length)
					{
						for (int j = num2; j > 0; j--)
						{
							if (base.IsDelimiter(s, i + j - 1))
							{
								num2 = j;
								break;
							}
						}
					}
					if (num2 <= 0)
					{
						num2 = 1;
					}
					num2 = Math.Min(num2, length - i);
					StringItem stringItem = new HintSyntaxPaint.HintItem(s.Substring(i, num2), width);
					if (data != null)
					{
						Array.Copy(data, i, stringItem.TextData, 0, num2);
					}
					this.strings.Add(stringItem);
					i += num2;
					num = EditConsts.MaxHintWindowWidth;
				}
			}
		}
		protected virtual void TextChanged()
		{
			this.strings.Clear();
			if (base.Provider != null && this.selectedIndex >= 0 && this.selectedIndex < base.Provider.Count)
			{
				base.AddMultiLine(this.GetNameStr(), (this.Lexer != null) ? this.Lexer.DefaultState : 0, this.startPos, true, true);
				string description = base.Provider.GetDescription(this.selectedIndex);
				if (!string.IsNullOrEmpty(description))
				{
					base.AddMultiLine(description, (this.Lexer != null) ? this.Lexer.DefaultState : 0, this.startPos, true, true);
				}
			}
		}
		protected string GetNameStr()
		{
			string text = string.Empty;
			if (base.Provider != null && this.selectedIndex >= 0 && this.selectedIndex < base.Provider.Count)
			{
				if (base.Provider.ColumnCount == 0)
				{
					text = base.Provider.GetName(this.selectedIndex);
				}
				else
				{
					text = string.Empty;
					for (int i = 0; i < base.Provider.ColumnCount; i++)
					{
						if (base.Provider.ColumnVisible(i))
						{
							string columnText = base.Provider.GetColumnText(this.selectedIndex, i);
							if (!string.IsNullOrEmpty(columnText))
							{
								if (text == string.Empty)
								{
									text = columnText;
								}
								else
								{
									text = text + (base.Provider.ColumnSpace(i) ? ' '.ToString() : string.Empty) + columnText;
								}
							}
						}
					}
				}
			}
			return text;
		}
		protected override void GetString(int index, ref string line, ref StringItemInfo[] colorData)
		{
			StringItem stringItem = this.strings[index];
			line = stringItem.String;
			colorData = stringItem.TextData;
		}
		public HintSyntaxPaint(Painter painter, Control control) : base(painter, control)
		{
			this.strings = new List<StringItem>();
		}
		public Size UpdateSize()
		{
			this.TextChanged();
			int num = 0;
			for (int i = 0; i < this.strings.Count; i++)
			{
				int val = ((HintSyntaxPaint.HintItem)this.strings[i]).Width + this.MeasureArrows();
				num = Math.Max(num, val);
			}
			return new Size(num + 6, (this.painter.FontHeight + 4) * Math.Max(this.strings.Count, 1) + 1);
		}
		public void ProviderChanged(ICodeCompletionProvider provider, int index)
		{
			base.Provider = provider;
			this.selectedIndex = index;
		}
		public bool UpdateHint()
		{
			string b = this.GetNameStr();
			bool result;
			if (this.nameStr != b)
			{
				this.nameStr = b;
				result = true;
			}
			else
			{
				result = false;
			}
			return result;
		}
		public override void DrawLine(int index, string line, StringItemInfo[] colorData, Point position, Rectangle clipRect)
		{
			if (index == 0 && this.NeedArrows)
			{
				this.DrawArrows();
			}
			base.DrawLine(index, line, colorData, position, clipRect);
		}
		public override void PaintSyntax(Painter painter, int startLine, int endLine, Point position, Rectangle rect, Point location, bool specialPaint)
		{
			painter.BackColor = this.control.BackColor;
		    painter.fontStyle = FontStyle.Regular;
		    painter.FillRectangle(0, 0, rect.Width, rect.Height);
			if (base.Provider != null)
			{
				painter.TextColor = this.control.ForeColor;
				painter.Opaque = false;
				int num = 1;
				for (int i = 0; i < this.strings.Count; i++)
				{
					int x;
					if (i == 0 && base.Provider.Count > 1)
					{
						this.DrawArrows();
						x = this.MeasureArrows() + 2;
					}
					else
					{
						x = this.MeasureArrows() + 2;
					}
					this.DrawLine(i, new Point(x, num), rect);
					num += painter.FontHeight + 4;
				}
			}
		}
	}
}
